package com.umeox.watch.moto.dataservice.stub;

import android.os.IBinder;
import android.os.RemoteException;

import com.alibaba.fastjson.JSONObject;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.mqtt.base.AError;
import com.umeox.moto.mqtt.base.ARequest;
import com.umeox.moto.mqtt.base.AResponse;
import com.umeox.watch.moto.apiclient.model.FileSignDTO;
import com.umeox.watch.moto.dataservice.BuildConfig;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.dataservice.constants.MqttConstants;
import com.umeox.watch.moto.dataservice.interfaces.IChat;
import com.umeox.watch.moto.dataservice.mqtt.PayloadMessage;
import com.umeox.watch.moto.dataservice.mqtt.bean.FileSignBody;
import com.umeox.watch.moto.dataservice.mqtt.impl.MqttServiceDelegate;
import com.umeox.watch.moto.dataservice.mqtt.interfaces.IPublishListener;
import com.umeox.watch.moto.dataservice.services.ApiService;

import net.vidageek.mirror.dsl.Mirror;

import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

public class ChatStub extends android.os.Binder implements IChat {

    public ChatStub() {
        this.attachInterface(this, DESCRIPTOR);
    }

    public static void registerBinder() {
        try {
            new Mirror().on("android.os.ServiceManager").invoke().method("addService").withArgs(BuildConfig.chatBinderName, new ChatStub());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public IBinder asBinder() {
        return this;
    }

    @Override
    public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws RemoteException {
        String descriptor = DESCRIPTOR;
        switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(descriptor);
                return true;
            }
            case TRANSACTION_GETCHATMSG: {
                data.enforceInterface(descriptor);
                String deviceId = data.readString();
                String fid = data.readString();
                long lastMsgId = data.readLong();
                byte[] result = this.getChatMsg(deviceId, fid, lastMsgId);
                reply.writeNoException();
                reply.writeByteArray(result);
                return true;
            }
            case TRANSACTION_SENDCHATMSG: {
                data.enforceInterface(descriptor);
                String fid = data.readString();
                String tid = data.readString();
                int type = data.readInt();
                long msgTime = data.readLong();
                int msgType = data.readInt();
                String msgBody = data.readString();
                String result = this.sendChatMsg(fid, tid, type, msgTime, msgType, msgBody);
                reply.writeNoException();
                reply.writeString(result);
                return true;
            }
            case TRANSACTION_UPLOADFILE: {
                data.enforceInterface(descriptor);
                String filePath = data.readString();
                String result = this.uploadFile(filePath);
                reply.writeNoException();
                reply.writeString(result);
                return true;
            }
            case TRANSACTION_DOWNLOADFILE: {
                data.enforceInterface(descriptor);
                String url = data.readString();
                String filePath = data.readString();
                boolean result = this.downloadFile(url, filePath);
                reply.writeNoException();
                reply.writeByte((byte) (result ? 1 : 0));
                return true;
            }
            default: {
                return super.onTransact(code, data, reply, flags);
            }
        }
    }

    @Override
    public byte[] getChatMsg(String deviceId, String fid, long lastMessageId) throws RemoteException {
//        ChatMsgProtos.ChatMsgs chatMsgs = null;
//        try {
//            chatMsgs = ApiService.getChatMessage(deviceId, fid, lastMessageId);
//        } catch (Exception e) {
//            throw new RemoteException(e.getMessage());
//        }
//        Logger.i(String.format("\n获取{%s}与{%s}在消息{%d}后的语聊消息：\n%s", deviceId, fid, lastMessageId, chatMsgs.toString()));
//        if (chatMsgs != null && chatMsgs.getMsgCount() > 0) {
//            return chatMsgs.toByteArray();
//        }
        return null;
    }

    @Override
    public String sendChatMsg(String fid, String tid, int type, long msgTime, int msgType, String msgBody) throws RemoteException {
        String msgId;
        try {
            msgId = ApiService.sendChatMessage(fid, tid, type, msgTime, msgType, msgBody);
        } catch (Exception e) {
            throw new RemoteException(e.getMessage());
        }
        Logger.i(String.format(Locale.getDefault(), "\n{%s}发送消息{%s}给{%s}>>>%s", fid, msgBody, tid, msgId));
        return msgId;
    }


    @Override
    public String uploadFile(String filePath) {
        //getFileSign
        JSONObject jsonObject = new JSONObject();
        FileSignBody fileSignBody = FileSignBody.Builder.aFileSignBody()
                .setHolderId(DataProvider.getHolderId())
                .setServiceType(1)
                .setFileType(11) //11：语聊文件
                .build();
        JSONObject paramsJsonObject = (JSONObject) JSONObject.toJSON(fileSignBody);
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_FILE_SIGN);
        jsonObject.put("params", paramsJsonObject);
        final AtomicReference<FileSignDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getFileSign(jsonObject, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getFileSign成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    FileSignDTO fileSignDTO = jsonObject.getObject("result", FileSignDTO.class);
                    result.set(fileSignDTO);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getFileSign失败：" + error.getMsg());
                downLatch.countDown();
            }
        });
        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(30, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        if (result.get() != null) {
            String url = ApiService.uploadFile(result.get(), filePath);
            Logger.i(String.format("上传文件{%s}>>>{%s}", filePath, url));
            return url;
        }
        return null;
    }

    @Override
    public boolean downloadFile(String url, String filePath) {
        return ApiService.downloadFile(url, filePath);
    }
}
